<!--
 * @Author: your name
 * @Date: 2021-04-06 15:43:23
 * @LastEditTime: 2021-04-08 13:45:33
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /Interview Files/大纲/1103节流防抖.html
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>防抖和节流</title>
</head>

<body>
    <p>
        函数防抖(debounce)：触发高频事件后n秒内函数只会执行一次，如果n秒内高频事件再次被触发，则重新计算时间。
    </p>
    <p>
        函数节流(throttle)：高频事件触发，但在n秒内只会执行一次，所以节流会稀释函数的执行频率。
    </p>
</body>

</html>
<script>
    //节流:
    //实现方式：每次触发事件时，如果当前有等待执行的延时函数，则直接return
    function throttle(fn, delay) {
        // [ˈθrɑːtl]
        let canRun = true; // 通过闭包保存一个标记
        return function() {
            // 在函数开头判断标记是否为true，不为true则return
            if (!canRun) return;
            // 立即设置为false
            canRun = false;
            // 将外部传入的函数的执行放在setTimeout中
            setTimeout(() => {
                // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
                // 当定时器没有执行的时候标记永远是false，在开头被return掉
                fn.apply(this, arguments);
                canRun = true;
            }, delay);
        };
    }

    function sayHi(e) {
        console.log('节流：', e.target.innerWidth, e.target.innerHeight);
    }
    window.addEventListener('resize', throttle(sayHi, 500));

    /*=====================================================================================================*/

    //防抖:
    //实现方式：每次触发事件时设置一个延迟调用方法，并且取消之前的延时调用方法
    //缺点：如果事件在规定的时间间隔内被不断的触发，则调用方法会被不断的延迟
    function debounce(fn, delay) {
        // [di'bauns]
        var timeout = null; // 创建一个标记用来存放定时器的返回值
        return function(e) {
            // 每当用户输入的时候把前一个 setTimeout clear 掉
            clearTimeout(timeout);
            // 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发，就不会执行 fn 函数
            timeout = setTimeout(() => {
                fn.apply(this, arguments);
            }, delay);
        };
    }
    // 处理函数
    function handle() {
        console.log('防抖：', Math.random());
    }

    //滚动事件
    window.addEventListener('scroll', debounce(handle, 500));
</script>